/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.samples.rtp;

import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.MediaLocator;
import javax.media.format.VideoFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.rtp.RTPConnector;
import javax.media.rtp.RTPManager;
import javax.media.rtp.SendStream;

/**
 * This class transmits a video stream with an RTPConnector
 * main method also starts a Receiver on the same topic
 * Therefore it receives it own stream too.
 * It will also receive any other stream sent to the same topic.
 *
 * @author Ahmet Uyar
 * $Date$
 */

public class Transmitter{

    private RTPManager rtpManager = null;
    private DataSource dataSource = null;
    private RTPConnector connector = null;

    /**
     * construct the transmitter with a RTPConnector
     */
     public Transmitter(RTPConnector connector) {
        this.connector = connector;
     }

    /**
     * set the datasource
     */
    public void setDataSource(DataSource ds){

      if(ds == null){
         System.out.println("DataSource is null.");
         return;
      }

      if(this.dataSource != null){
         System.out.println("datasource is already set.");
         return;
      }

      this.dataSource = ds;
    }

    /**
     * Stops the transmission if already started
     */
    public void close() {

      if(dataSource != null)
         dataSource.disconnect();

      if(rtpManager != null){
         rtpManager.removeTargets( "Session ended.");
         rtpManager.dispose();
         rtpManager = null;
      }
    }

    /**
     * Initialize the RTPManager and start transmitting data
     * Return null if successful, otherwise a string explaining the problem
     */
   public String start() {

      try {

         rtpManager = RTPManager.newInstance();
         rtpManager.initialize(connector);

         SendStream sendStream = rtpManager.createSendStream(dataSource, 0);
         sendStream.start();
         System.out.println("Started transmitting data with the ssrc: "+sendStream.getSSRC());

      } catch (javax.media.format.UnsupportedFormatException  e) {
         System.out.println(this.getClass().getName()+"  Exception while trying to initialize rtp manager. The message is: "+e.getMessage());
         System.out.println(this.getClass().getName()+"  the failed exception is: "+e.getFailedFormat());
         return e.getMessage();
      } catch(Exception e){
         return e.getMessage();
      }

      return null;
   }

   public static void main(String args[]) throws Exception{

      if(args.length != 3){
         printUsage();
         return;
      }

      String brokerIP = args[0];
      int brokerPort = Integer.parseInt( args[1] );
      int topicNumber = Integer.parseInt( args[2] );

      MediaLocator ml = getMediaLocator();
      //construct the media capturer
      ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW);
      VideoFormat format = new VideoFormat(VideoFormat.H263_RTP);
      MediaCapturer mc = new MediaCapturer(ml, cd, format);

      //construct a clone for the datasource so that we can both play and transmit it
      DataSource dataSource = mc.getDataSource();
//      dataSource = javax.media.Manager.createCloneableDataSource(dataSource);
//      DataSource clonedDataSource = ((SourceCloneable)dataSource).createClone();

      //play the video
//      new PlayerWindow(dataSource);

      //send the video
      NaradaRTPConnector connector = new NaradaRTPConnector(brokerIP, brokerPort, topicNumber);
      Transmitter ct = new Transmitter(connector);
      ct.setDataSource( dataSource );
      String result = ct.start();
      if (result != null) {
         System.err.println("Failed to initialize the transmitter. The message is: "+result);
      }else{
         System.err.println("  - Started transmitting data to the topic: " + topicNumber +" at the broker "+brokerIP+":"+brokerPort);
      }

      //start the receiver
      Receiver.startReceiver(brokerIP, brokerPort, topicNumber);

      //wait indefinetely
      while( true ){
         try{
            Thread.sleep(10000);
         }catch(java.lang.InterruptedException ie){ie.printStackTrace();}
       }

   }//end of main

   public static void printUsage(){
      System.out.println("Usage: java cgl.narada.samples.rtp.Transmitter  <Broker IP>   <Broker Port>   <Topic Number>");
   }

   /**
    * get a MediaLocator from a capture device for video
    */
   public static MediaLocator getMediaLocator(){

      VideoFormat videoFormat = new VideoFormat(VideoFormat.RGB);
      java.util.Vector deviceList = CaptureDeviceManager.getDeviceList ( videoFormat );
      MediaLocator ml = null;
      if(deviceList.size() == 0){
         System.out.println("There is no video device on the computer or You did not run JMFRegistry");
         System.out.println("if you had installed the JMF but did not run JMFRegistry, please run JMFRegistry and try again");
         System.out.println("It is in the same folder as JMStudio in applications menu");

      }else if(deviceList.size() == 1){
         ml = ((CaptureDeviceInfo)deviceList.get(0)).getLocator();

      }else{
         System.out.println("There are more than one Video device on this machine.");
         System.out.println("We will try the first one");
         ml = ((CaptureDeviceInfo)deviceList.get(0)).getLocator();
      }

      return ml;
   }



}
